package com.cuit.qx.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

/**
 * 
 * FTP工具类
 * 
 * @author hong
 *
 */
public class FtpUtil {

	private static final Logger logger = Logger.getLogger(FtpUtil.class);

	private FTPClient ftpClient = null;

	private boolean success = true;

	private List<String> arFiles = null;

	public boolean getSuccess() {
		return success;
	}

	/**
	 * 
	 * @param ftpHost
	 *            ip地址
	 * @param ftpPassword
	 *            密码
	 * @param ftpUserName
	 *            账号
	 * @param ftpPort
	 *            端口
	 */
	public FtpUtil(String ftpHost, String ftpPassword, String ftpUserName, int ftpPort) {
		try {
			ftpClient = new FTPClient();

			if (!ftpClient.isConnected()){
				ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
			}
			ftpClient.setSoTimeout(60000);
			ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
			if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
				logger.error("未连接到FTP，用户名或密码错误。");
				ftpClient.disconnect();
				this.success = false;
			} else {
				logger.info("========FTP链接成功==========");
				// 相关设置
				ftpClient.setControlEncoding("UTF-8"); // 中文支持
				ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
				ftpClient.enterLocalPassiveMode();
			}
		} catch (SocketException e) {
			e.printStackTrace();
			logger.error("FTP的IP地址可能错误，请正确配置。");
			this.success = false;
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("FTP的端口错误,请正确配置。");
			this.success = false;
		}
	}

	/**
	 * 读取文件
	 * 
	 * @param remotePath
	 *            ftp路径
	 * @param fileName
	 *            要读取的文件名
	 * @return
	 */
	public InputStream readFile(String ftpPath, String fileName) {
		InputStream in = null;
		String remotePath = ftpPath + "\\" + fileName;
		// System.out.println("开始读取绝对路径:" + remotePath + " 文件");
		try {
			// OutputStream out = new FileOutputStream(new
			// File("C:\\Users\\hong\\Desktop\\"+fileName));
			ftpClient.changeWorkingDirectory(ftpPath);
			in = ftpClient.retrieveFileStream(fileName);
			// ftpClient.retrieveFile(fileName, out);
		} catch (FileNotFoundException e) {
			logger.error("没有找到:" + remotePath + " 文件");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("文件读取错误。");
		}
		return in;
	}

	/**
	 * 读取文件
	 * 
	 * @param
	 *            ftp路径
	 * @param fileName
	 *            要读取的文件名
	 * @return
	 */
	public OutputStream readFileOut(String ftpPath, String fileName) {
		OutputStream out = null;
		String remotePath = ftpPath + "\\" + fileName;
		try {
			ftpClient.changeWorkingDirectory(ftpPath);
			out = ftpClient.storeFileStream(fileName);
			// ftpClient.retrieveFile(fileName, out);
		} catch (FileNotFoundException e) {
			logger.error("没有找到:" + remotePath + " 文件");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("文件读取错误。");
		}
		return out;
	}

	/**
	 * 下载文件到本地
	 * 
	 * @param ftpPath
	 * @param fileName
	 * @param localFile
	 */
	public void downloadFile(String ftpPath, String fileName, OutputStream localFile) {
		try {
			ftpClient.changeWorkingDirectory(ftpPath);
			ftpClient.retrieveFile(fileName, localFile);
			localFile.close();
		} catch (IOException e) {
			close();
			e.printStackTrace();
		}

	}

	/**
	 * 
	 * 根据文件正则表达式得到最新文件
	 * 
	 * @param ftpPath
	 * @param fileNameReg
	 * @return
	 */
	public String getNCFileNameBestTime(String ftpPath, String fileNameReg) {
		try {
			ftpClient.changeWorkingDirectory(ftpPath);
			String[] filenames = ftpClient.listNames();
			Map<Long, String> file_map = new HashMap<Long, String>();
			List<Long> list = new ArrayList<Long>();
			for (String filename : filenames) {
				if (isPattern(filename, fileNameReg)) {
					String s = filename.substring(0, filename.length() - 5);
					file_map.put(Long.parseLong(s.split("-")[2]), filename);
					list.add(Long.parseLong(s.split("-")[2]));
				}
			}
			if (list.size() == 0)
				return null;
			Collections.sort(list);
			return file_map.get(list.get(list.size() - 1));
		} catch (IOException e) {
			close();
			e.printStackTrace();
		} // 转移到FTP服务器目录
		return null;
	}

	/**
	 * 
	 * 根据文件正则表达式得到最新文件
	 * 
	 * @param ftpPath
	 * @param fileNameReg
	 * @return
	 */
	public String getGRB2FileNameBestTime(String ftpPath, String fileNameReg) {
		try {
			ftpClient.changeWorkingDirectory(ftpPath);
			String[] filenames = ftpClient.listNames();
			Map<Long, String> file_map = new HashMap<Long, String>();
			List<Long> list = new ArrayList<Long>();
			for (String filename : filenames) {
				if (isPattern(filename, fileNameReg)) {
					String s = filename.substring(0, filename.length() - 5);
					file_map.put(Long.parseLong(s.split("_")[8]), filename);
					list.add(Long.parseLong(s.split("_")[8]));
				}
			}
			if (list.size() == 0)
				return null;
			Collections.sort(list);
			return file_map.get(list.get(list.size() - 1));
		} catch (IOException e) {
			close();
			e.printStackTrace();
		} // 转移到FTP服务器目录
		return null;
	}

	/**
	 * 
	 * 更具时间删除历史文件
	 */
	public void deleteFileByTime(String ftpPath, Long time) {
		try {
			ftpClient.changeWorkingDirectory(ftpPath);
			FTPFile[] fs = ftpClient.listFiles();
			for (FTPFile ff : fs) {
				if (ff.getTimestamp().getTimeInMillis() < time) {
					ftpClient.deleteFile(ff.getName());
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} // 转移到FTP服务器目录
	}

	/**
	 * 关闭输入输出流
	 * 
	 */
	public void close() {
		if (ftpClient != null && ftpClient.isConnected()) {
			try {
				logger.info("========关闭ftp流==========");
				ftpClient.logout();
				// System.out.println("退出登录");
				ftpClient.disconnect();
				// System.out.println("关闭连接");
			} catch (IOException e) {
				// System.out.println("", e);
				System.gc();
				logger.error("============关闭流异常=============",e);
			}
		}
	}

	/**
	 * @Title: checkFtp @Description: 检查ftp是否可以连接 @param url @param username @param
	 * password @param remotePath @return boolean @author lqy @throws
	 */
	public boolean checkFtp(String remotePath) {

		boolean success = false;
		try {
			if (ftpClient != null && ftpClient.isConnected()) {
				ftpClient.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
				return true;
			}
		} catch (IOException e) {
			return success;
		} finally {
			close();
		}
		return success;
	}

	/**
	 * 
	 * 
	 * 匹配正则表达式
	 * 
	 */
	public static boolean isPattern(String fname, String pattern_str) {
		if (fname.matches(pattern_str))
			return true;
		return false;
	}

	// GDFS_NMC_OCBU_SFER_EDA10_ACWP_L10M_G01_20191225080007212.GRB2
	public static void zhengze(String s, int hour) {
		String file_name = null;
	}

	/**
	 * 递归遍历出目录下面所有文件
	 *
	 * @param pathName
	 *            需要遍历的目录，必须以"/"开始和结束
	 * @throws IOException
	 */
	public void List(String pathName) throws IOException {
		System.out.println("------------" + pathName);
		if (pathName.startsWith("/") && pathName.endsWith("/")) {
			arFiles = new ArrayList<String>();
			// 更换目录到当前目录
			ftpClient.changeWorkingDirectory(pathName);
			FTPFile[] files = ftpClient.listFiles();
			for (FTPFile file : files) {
				if (file.isFile()) {
					System.out.println(pathName + "   " + file.getName());
					arFiles.add(pathName + file.getName());
				} else if (file.isDirectory()) {
					// 需要加此判断。否则，ftp默认将‘项目文件所在目录之下的目录（./）’与‘项目文件所在目录向上一级目录下的目录（../）’都纳入递归，这样下去就陷入一个死循环了。需将其过滤掉。
					if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
						List(pathName + file.getName() + "/");
					}
				}
			}
		}
	}
	
	
	/**
     * 获取某个文件夹下的所有文件
     *
     * @param fileNameList 存放文件名称的list
     * @param path 文件夹的路径
     * @return
     */
    public void getAllFileName(String path,ArrayList<String> fileNameList) {
        //ArrayList<String> files = new ArrayList<String>();
        File file = new File(path);
        File[] tempList = file.listFiles();

        for (int i = 0; i < tempList.length; i++) {
            if (tempList[i].isFile()) {
              System.out.println("文     件：" + tempList[i]);
                //fileNameList.add(tempList[i].toString());
                fileNameList.add(tempList[i].getName());
            }
            if (tempList[i].isDirectory()) {
              System.out.println("文件夹：" + tempList[i]);
                getAllFileName(tempList[i].getAbsolutePath(),fileNameList);
            }
        }
        return;
    }




}
